<template>
  <div>
    <el-header class="header">
      <div class="top-box">
        <!-- 返回上级文件夹按钮 -->
        <i class="el-icon-arrow-left" @click="returnParentFolder"></i>
        <!-- 文件路径导航 -->
        <el-breadcrumb separator="/">
          <el-breadcrumb-item v-for="(path, index) in paths" :key="index">
            <el-link @click="jumpToFolder(index)" style="font-size: large;">{{ path.name }}</el-link>
          </el-breadcrumb-item>
        </el-breadcrumb>
      </div>
      <div class="top-button">
        <el-popover placement="left" trigger="click" width="255px">

          <el-upload class="upload-demo" ref="upload" action="" :http-request="upload"
                     :file-list="fileList" :auto-upload="false">
            <el-button slot="trigger" :icon="Plus" plain type="primary">选取文件</el-button>
            <el-button style="margin-left: 15px;" :icon="Select" type="success"
                       @click="submitUpload">确认上传
            </el-button>
          </el-upload>

          <template #reference>
            <el-button :icon="Upload" plain type="primary"></el-button>
          </template>
        </el-popover>
        <el-button style="margin-left:10px" :icon="FolderAdd"
                   @click="createFolder" plain type="primary"></el-button>
      </div>
    </el-header>
    <!-- 搜索框 -->
    <div class="search-box">
      <div style="width: 100%;">
        <el-input placeholder="请输入文件名" style="width: 94%; margin-left:10px" v-model.trim="keyword"
                  clearable @clear="resetData" @keyup.enter="searchFile()"></el-input>
        <el-button style="width: 5%;" type="primary" slot="append" :disabled="keyword === ''"
                   @click="searchFile()" :icon="Search"></el-button>
      </div>
    </div>
    <!-- 文件列表 -->
    <el-table ref="table" :data="files" empty-text="空文件夹" style="width: 100%"
              @row-click="enterFolder" v-loading="loading">
      <el-table-column label="文件名称">
        <template #default="scope">
          <!-- 文件夹图标 -->
          <el-icon v-if="scope.row.type === '文件夹'">
            <Folder/>
          </el-icon>
          <!-- 文件图标 -->
          <el-icon v-else>
            <Document/>
          </el-icon>
          {{ scope.row.name }}
        </template>
      </el-table-column>
      <el-table-column align="center" label="类型" prop="type" width="100"></el-table-column>
      <el-table-column align="center" label="大小" prop="size" width="100"></el-table-column>
      <el-table-column align="center" label="创建时间" prop="createTime" width="200"></el-table-column>
      <el-table-column align="center" label="修改时间" prop="updateTime" width="200"></el-table-column>
      <el-table-column align="center" label="操作" width="100">
        <template #default="scope">
          <!-- 操作下拉菜单 -->
          <el-dropdown @command="handleCommand($event, scope.row)" trigger="click">
            <!-- 操作图标 -->
            <el-button :icon="Operation" plain type="primary"></el-button>
            <template #dropdown>
              <el-dropdown-menu>
                <el-dropdown-item command="rename" :icon="Edit">重命名</el-dropdown-item>
                <el-dropdown-item command="remove" :icon="Delete">删除</el-dropdown-item>
                <el-dropdown-item :disabled="scope.row.type === '文件夹'"
                                  command="download" :icon="Download">下载
                </el-dropdown-item>
                <el-dropdown-item v-if="scope.row.shared"
                                  command="stopShare" :icon="Share">停止分享
                </el-dropdown-item>
                <el-dropdown-item v-else command="share" :icon="Share">分享</el-dropdown-item>
              </el-dropdown-menu>
            </template>
          </el-dropdown>
        </template>
      </el-table-column>
    </el-table>
    <el-footer>
      <div style=" margin: 20px auto;">
        <!-- 分页器 -->
        <el-pagination :hide-on-single-page="true" class="pagination" background @size-change="handleSizeChange"
                       @current-change="handleCurrentChange" :current-page="page" :page-size="limit"
                       layout="total,prev, pager, next, jumper" :total="total">
        </el-pagination>
      </div>
    </el-footer>
  </div>
</template>
<script>
import {createFolder, deleteFile, downloadFile, getFiles, searchFile, updateFile, uploadFile} from '@/api/file'
import {ElMessage, ElMessageBox} from "element-plus";
import {
  Delete,
  Document,
  Download,
  Edit,
  Folder,
  FolderAdd,
  Operation, Plus,
  Search, Select,
  Share,
  Upload
} from "@element-plus/icons-vue";

export default {
  name: 'File-Manage',
  components: {Document, Folder},
  computed: {
    Select() {
      return Select
    },
    Plus() {
      return Plus
    },
    Search() {
      return Search
    },
    Upload() {
      return Upload
    },
    FolderAdd() {
      return FolderAdd
    },
    Delete() {
      return Delete
    },
    Download() {
      return Download
    },
    Share() {
      return Share
    },
    Edit() {
      return Edit
    },
    Operation() {
      return Operation
    }
  },
  data() {
    return {
      files: [],
      total: 0,
      page: 1,
      keyword: '',
      limit: 10,
      paths: [{id: 0, name: '根目录'}],
      loading: true,
      fileList: []
    }
  },
  created() {
    this.getFiles(0)
  },
  methods: {
    //分页组件
    handleSizeChange(val) {
      this.limit = val;
    },
    handleCurrentChange(val) {
      this.page = val;
      let parentId = this.paths[this.paths.length - 1].id
      this.getFiles(parentId)
    },
    getFiles(parentId) {
      this.loading = true
      getFiles({parentId, pageNumber: this.page})
          .then(res => {
            if (res.code === 0) {
              this.files = res.data.records
              this.total = Number(res.data.total);
              // this.$refs.table.doLayout()
              this.loading = false
            }
          })
    },
    enterFolder(row, column) {
      if (row.type === '文件夹' && column.label !== '操作') {
        this.getFiles(row.id)
        this.paths.push({id: row.id, name: row.name})
      }
    },
    jumpToFolder(index) {
      if (index + 1 < this.paths.length) {
        this.getFiles(this.paths[index].id)
        this.paths.splice(index + 1)
      }
    },
    returnParentFolder() {
      if (this.paths.length > 1) {
        this.paths.pop()
        this.getFiles(this.paths[this.paths.length - 1].id)
      }
    },
    //确认上传
    submitUpload() {
      this.$refs.upload.submit()
    },
    async upload(params) {
      let formData = new FormData()
      formData.append('multipartFile', params.file)
      formData.append('parentId', this.paths[this.paths.length - 1].id)
      const res = await uploadFile(formData)
      if (res.code === 0) {
        ElMessage.success(res.msg)
        this.fileList = []
        this.files.push(res.data)
      }
    },
    //创建文件夹
    createFolder() {
      ElMessageBox.prompt('请输入文件夹名', '新建文件夹', {
        inputPattern: /^.{1,50}$/,
        inputErrorMessage: '文件夹名应为1-50个字符'
      }).then(({value}) => {
        let formData = new FormData()
        formData.append('name', value)
        formData.append('parentId', this.paths[this.paths.length - 1].id)
        createFolder(formData).then(res => {
          if (res.code === 0) {
            ElMessage.success(res.msg)
            if (this.files.length === 10) {
              this.files.splice(this.files.length - 1, 1)
            }
            this.files.push(res.data)
          }
        })
      }).catch(() => {
        ElMessage.warning('操作已取消！')
      })
    },
    //下载文件
    download(row) {
      ElMessageBox.prompt('请输入文件名', '下载', {
        inputValue: row.name,
        inputPattern: /^.{1,50}$/,
        inputErrorMessage: '文件名应为1-50个字符'
      }).then(async ({value}) => {
        const response = await downloadFile(row.id)
        if (response) {
          let link = document.createElement('a')
          let blob = new Blob([response.data], {type: 'application/octet-stream'})
          link.href = window.URL.createObjectURL(blob)
          link.setAttribute('download', value)
          link.click()
        }
      }).catch(() => {
        ElMessage.warning('已取消下载！')
      })
    },
    //重命名
    rename(row) {
      ElMessageBox.prompt('请输入新文件名', '重命名', {
        inputValue: row.name,
        inputPattern: /^.{1,50}$/,
        inputErrorMessage: '文件名应为1-50个字符'
      }).then(({value}) => {
        updateFile({id: row.id, name: value}).then(res => {
          if (res.code === 0) {
            ElMessage.success(res.msg)
            row.name = value
          }
        })
      }).catch(() => {
        ElMessage.warning('已取消重命名！')
      })
    },
    //删除
    remove(row) {
      ElMessageBox.confirm('确定删除“ ' + row.name + ' ”？', '删除').then(() => {
        deleteFile(row.id).then(res => {
          if (res.code === 0) {
            let index = this.files.indexOf(row)
            this.files.splice(index, 1)
            ElMessage.success('删除成功！')
          }
        })
      }).catch(() => {
        ElMessage.warning('已取消删除！')
      })
    },
    //共享
    share(row) {
      ElMessageBox.confirm('确定分享“ ' + row.name + ' ”？', '分享').then(() => {
        updateFile({id: row.id, shared: true}).then(res => {
          if (res.code === 0) {
            row.shared = true
            ElMessage.success('分享成功！')
          }
        })
      }).catch(() => {
        ElMessage.warning('已取消分享！')
      })
    },
    //取消共享
    stopShare(row) {
      ElMessageBox.confirm('确定停止分享“ ' + row.name + ' ”？', '停止分享').then(() => {
        updateFile({id: row.id, shared: false}).then(res => {
          if (res.code === 0) {
            row.shared = false
            ElMessage.success('停止分享成功！')
          }
        })
      }).catch(() => {
        ElMessage.warning('已取消停止分享！')
      })
    },
    handleCommand(command, row) {
      switch (command) {
        case 'download':
          this.download(row)
          break
        case 'rename':
          this.rename(row)
          break
        case 'remove':
          this.remove(row)
          break
        case 'share':
          this.share(row)
          break
        case 'stopShare':
          this.stopShare(row)
          break
      }
    },
    searchFile() {
      this.loading = true
      searchFile({name: this.keyword, pageNumber: this.page - 1}).then(res => {
        if (res.code === 0) {
          this.files = res.data.records
          this.total = +(res.data.total);
          this.loading = false
        }
      })
    },
    resetData() {
      let parentId = this.paths[this.paths.length - 1].id
      this.getFiles(parentId)
    }
  }
}
</script>

<style scoped>
.header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 0 20px;
}

.top-box {
  display: flex;
  align-items: center;
  font-size: large;
}

.top-button {
  display: flex;
  align-items: center;
}

.top-button el-upload {
  margin-right: 10px;
}


.search-box {
  margin: 15px 5px;
}

</style>
